package com.ezops.poc.validations.validators;

import java.lang.reflect.Field;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.ezops.annotation.EzopsDisplayName;
import com.ezops.model.DefaultFieldValidationError;
import com.ezops.poc.validations.result.ValidationResult;

/**
 * Checks if the field being passed is present in the model under test
 * 
 * @author vgaurav
 * 
 */
@Component
@Validator(name = "Mandatory")
public class MandatoryValidator extends AbstractValidator {

	private static final Logger logger = LoggerFactory
			.getLogger(MandatoryValidator.class);

	private boolean isMandatory;

	public MandatoryValidator() {

	}

	@Override
	public ValidationResult validateModel(Object model) {
		if (model == null) {
			throw new IllegalArgumentException("Can't not validate null model");
		}
		if (isMandatory == false) {
			// If field is not mandatory, no need to chk the presence of field.
			return ValidationResult.getValidResponse();
		}

		Object value;

		try {
			final Field field = model.getClass().getDeclaredField(fieldName);
			field.setAccessible(true);
			value = field.get(model);
			if (value != null && !value.toString().trim().equals("")) {
				return ValidationResult.getValidResponse();
			}
		} catch (Exception ex) {
			try {
				for (Field field : model.getClass().getDeclaredFields()) {
					if (field.getAnnotation(EzopsDisplayName.class) != null) {
						if (field.getAnnotation(EzopsDisplayName.class).name()
								.equalsIgnoreCase(fieldName)) {
							this.fieldName = field.getName();
						}
					}
				}
				final Field field = model.getClass().getField(fieldName);
				field.setAccessible(true);
				value = field.get(model);
				if (value != null && !value.toString().trim().equals("")) {
					return ValidationResult.getValidResponse();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		logger.debug("Mandatoty validaton failed for field " + fieldName
				+ " .model -" + model.toString());
		return ValidationResult
				.getErrorResponse(new DefaultFieldValidationError(
						"The field name " + fieldName + " is not present.",
						fieldName, null));
		// field value is null. then only this validation can fail. no need to
		// use value variable for setting fieldValue.

	}

	public void init(String fieldName, String... values) {
		this.ezopsDisplayFieldName = fieldName;
		if (values != null && values.length != 0) {
			isMandatory = (values[0].equalsIgnoreCase("Y")) ? true : false;
		}
	}
}
